package com.common.test;

import java.io.File;
import java.util.List;

import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.UnexpectedTagNameException;

import com.common.util.BrowserSetupConfig;
import com.common.util.JenkinsUtil;

public class DefaultElement {
	
    private WebDriver driver;

    private String findName;

    private String findValue;

    private String desc;
    
    Logger log = Logger.getLogger(DefaultElement.class);

    public WebDriver getDriver(){
        return driver;
    }
    
    public void setfindName(String findName) throws Exception{
        if(!findName.equals("id")&&!findName.equals("name")&&!findName.equals("linkText")&&!findName.equals("partialLinkText")
         &&!findName.equals("xpath")&&!findName.equals("tagName")&&!findName.equals("className")&&!findName.equals("cssSelector")){
        	handlefailure("查找方式不合法，为['" + findName + "']");
        }
    	this.findName = findName;
    }

    public String getfindName(){
        return findName;
    }
    
    public void setfindValue(String findValue){
    	this.findValue = findValue;
    }

    public String getfindValue(){
        return findValue;
    }
    
    public void setDesc(String desc){
    	this.desc = desc;
    }
    
    public String getDesc(){
    	return desc;
    }

    public DefaultElement() {
        // TODO Auto-generated constructor stub
    }

    public DefaultElement(WebDriver driver, String findName, String findValue, String desc) throws Exception{
        this.driver = driver;
        this.findName = findName;
        this.findValue = findValue;
        this.desc = desc;
        if(!findName.equals("id")&&!findName.equals("name")&&!findName.equals("linkText")&&!findName.equals("partialLinkText")
         &&!findName.equals("xpath")&&!findName.equals("tagName")&&!findName.equals("className")&&!findName.equals("cssSelector")){
    		handlefailure("查找方式不合法，为" + findName);
        }
    }

    /**
     * 得到原生WebElement对象
     */
    public WebElement getNativeElement(){
        WebElement element = null;
        switch(findName){
            case "id":
                element = driver.findElement(By.id(findValue));
                break;
            case "name":
                element = driver.findElement(By.name(findValue));
                break;
            case "linkText":
                element = driver.findElement(By.linkText(findValue));
                break;
            case "partialLinkText":
                element = driver.findElement(By.partialLinkText(findValue));
                break;
            case "xpath":
                element = driver.findElement(By.xpath(findValue));
                break;
            case "tagName":
                element = driver.findElement(By.tagName(findValue));
                break;
            case "className":
                element = driver.findElement(By.className(findValue));
                break;
            case "cssSelector":
                element = driver.findElement(By.cssSelector(findValue));
                break;
        }
        return element;
    }

    /**
     * 点击
     * @throws Exception 
     */
    public void click() throws Exception{
    	WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
        element.click();
    }
    
    /**
     * js方法点击
     * @throws Exception 
     */
    public void clickByJs() throws Exception{
    	WebElement element = null;
    	JavascriptExecutor jse=(JavascriptExecutor) driver;
    	try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	jse.executeScript("arguments[0].click();", element);
    }
    
    /**
     * 双击
     * @throws Exception 
     */
    public void doubleclick() throws Exception{
    	WebElement element = null;
    	try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	Actions builder = new Actions(driver);
    	builder.doubleClick(element);
    }
    
    /**
     * submit按钮
     * @throws Exception 
     */
    public void submit() throws Exception{
    	WebElement element = null;
    	try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	try {
			element.submit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(e.getMessage().contains("Element was not in a form")){
				handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件不在form表单下，无法submit");
			}else{
				handlefailure(e.getMessage());
			}
		}
    }
    
    /**
     * 清空输入框内容
     * @throws Exception 
     */
    public void clear() throws Exception{
    	WebElement element = null;
    	try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	try {
			element.clear();
		} catch (InvalidElementStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件不是可编辑输入框，无法clear");
		}
    }

    /**
     * 输入框输入
     * @throws Exception 
     */
    public void type(String str) throws Exception{
        WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
        element.sendKeys(str);
    }
    
    /**
     * 日期输入框输入
     * @throws Exception 
     */
    public void typeDate(String str) throws Exception{
    	WebElement element = null;
    	JavascriptExecutor jse=(JavascriptExecutor) driver;
    	try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	jse.executeScript("arguments[0].value='"+str+"';", element);
    }
    
    /**
     * 上传文件操作
     * @throws Exception 
     */
    public void chooseFile(String filename) throws Exception{
    	WebElement element = null;
    	try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	String absolutepath = "";
    	int remoteOrNot = BrowserSetupConfig.REMOTEORNOT;
    	if(remoteOrNot == 0){
    		String path = this.getClass().getResource("").getPath();
    		log.info("path is " + path);
    		int idx = path.indexOf("/target");
    		path = path.substring(1, idx+1);
    		File file = new File(path + "src/main/resources/data/" + filename);
    		absolutepath = file.getAbsolutePath().replaceAll("/", "\\");
    	}else{
    		absolutepath = "\\\\" + JenkinsUtil.HOSTNAME + "\\" + JenkinsUtil.PATH + "\\" + filename.replaceAll("/", "\\");
    	}
    	log.info("上传文件路径为 " + absolutepath);
    	element.sendKeys(absolutepath);
    }

    /**
     * 下拉框选择方式一 根据选项文字选择
     * @throws Exception 
     */
    public void selectOptionByText(String text) throws Exception{
    	WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
        Select selectelement = null;
        try {
			selectelement = new Select(element);
		} catch (UnexpectedTagNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件的tag是'" + element.getTagName() + "'，不是选择框");
		}
        try {
			selectelement.selectByVisibleText(text);
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的选择框控件没有 '" + text + "'这个文字选项");
		}
    }
    
    /**
     * 下拉框选择方式二 根据index选择
     * @throws Exception 
     */
    public void selectOptionByIndex(int index) throws Exception{
    	WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
        Select selectelement = null;
        try {
			selectelement = new Select(element);
		} catch (UnexpectedTagNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件的tag是'" + element.getTagName() + "'，不是选择框");
		}
        try {
			selectelement.selectByIndex(index);
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的选择框控件没有 '" + index + "'这个下拉index");
		}
    }
    
    /**
     * 返回下拉框所有选择的控件
     * @throws Exception 
     */
    public List<WebElement> getAllSelectedOptions() throws Exception{
    	WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
        Select selectelement = null;
        try {
			selectelement = new Select(element);
		} catch (UnexpectedTagNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件的tag是'" + element.getTagName() + "'，不是选择框");
		}
        List<WebElement> elementLst = selectelement.getAllSelectedOptions();
        return elementLst;
    }
    
    /**
     * 返回下拉框所有选择的控件中的第一个控件
     * @throws Exception 
     */
    public WebElement getSelectdOption() throws Exception{
    	WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
        Select selectelement = null;
        try {
			selectelement = new Select(element);
		} catch (UnexpectedTagNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件的tag是'" + element.getTagName() + "'，不是选择框");
		}
        WebElement selectele = selectelement.getFirstSelectedOption();
        return selectele;
    }
    
    /**
     * 得到控件上的文字信息
     * @throws Exception 
     */
    public String getText() throws Exception{
    	WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	String text = element .getText();
    	return text;
    }
    
    /**
     * 得到控件属性
     * @throws Exception 
     */
    public String getAttribute(String name) throws Exception{
    	WebElement element = null;
        try {
			element = getNativeElement();
		} catch (NoSuchElementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			handlefailure("报错类型为 " + e.getClass().getName() + " 页面上不存在控件查找方式为'" + findName + "'，控件查找值为'" + findValue + "'的控件");
		}
    	return element.getAttribute(name);
    }
    
    /**
     * 抛出异常
     */
    private void handlefailure(String msg) throws Exception{
    	throw new Exception(msg);
    }
}
